import router from '@/router'
import store from '@/store'
import axios from 'axios'
import { Message } from 'element-ui'

/*
  我们前端去请求后端接口

  开发前端页面的时候 请求的不是真实的线上接口 => 开发中很多操作是临时测试的 不可能去影响真实的用户数据  http://www.xx.com
  开发前端页面的时候 请求的另一套后端接口       http://www.xx-dev.com

  对我们提出了一个要求: 我将来怎么切换接口地址?
  1. 开发时 你就正常请求  http://www.xx-dev.com;
     要上线了 手动改一下baseURL  再yarn  build

  2. 环境变量?
    项目开发环境请求   http://localhost:9528/api/   接口
    项目生产环境请求   http://www.xxx.com/api/      接口

  前端开发 至少两套环境  开发环境  生产环境
  后端开发 至少两套环境  开发环境  生产环境
*/

const instance = axios.create({
  // baseURL: 'http://localhost:9528/api/',
  // baseURL: '/api', // 简写(你不和别人说请求谁 默认就是请求自己) + 代码baseURL再也不用跟着端口改了(自己拼接)
  // baseURL: process.env.NODE_ENV === 'development' ? '/api' : 'http://www.xxx.com/api',
  baseURL: process.env.VUE_APP_BASE_API,
  timeout: 10000
})

// 添加请求拦截器
instance.interceptors.request.use(function(config) {
  // 在发送请求之前做些什么
  // store.state.user.token   getToken()
  if (store.getters.token) config.headers.Authorization = 'Bearer ' + store.getters.token

  return config
}, function(error) {
  // 对请求错误做些什么
  return Promise.reject(error)
})

// 添加响应拦截器
instance.interceptors.response.use(function(response) {
  // 2xx 范围内的状态码都会触发该函数。
  // 对响应数据做点什么
  // console.log(response, 999)
  if (response.data instanceof Blob) {
    // 如果你是 blob 数据格式 说明这次响应的是二进制文件流
    // 我就不帮你解构了 直接响应原数据
    return response.data
  }

  const { success, data, message } = response.data

  // 当你发现response.data.success 是false 说明这次请求成功200 操作失败  希望他走.catch逻辑(必须返回一个失败的promise)
  if (success === false) {
    // 操作失败了 统一给个提示 (页面中就不需要自己.catch  不需要了!)
    Message.error(message)

    // 请求成功200 操作失败
    // Promise.reject(new Error(123)) 快速得到一个失败的promise   Promise.resolve(123)  快速得到一个成功的promise
    // return new Promise((resolve, reject) => {
    //   reject(123)
    // })
    // 优化一下: 往往promise成功了 也有一个值; 失败了 也会有一个error   axios().then((res) => {}).catch((error) => {})
    // 代码规范: 如果你自己new了一个promise  一定是对应有状态以及值!!!
    return Promise.reject(new Error(message))
  } else {
    // 请求成功200 操作成功
    return data
  }
}, function(error) {
  // 超出 2xx 范围的状态码都会触发该函数。
  // console.dir(error, 999)

  // 只要响应失败 就会走这个函数
  if (error.response.status === 401) {
    // token失效的情况:
    // 清token(本地+仓库) + 清用户资料(仓库)
    // 对于这种多次提交mutation的操作: 这边建议你封装一个action 提交两次mutation
    // 有的公司有一种开发规范: 页面中不允许调用mutation  你通过action去提交
    // store.commit('user/delToken')
    // store.commit('user/delUserInfo')
    store.dispatch('user/logout')
    // 跳转login
    router.push('/login')
    // 提示
    Message.error('token已失效, 请重新登录吧')
  } else {
    // 不是token失效的情况 简单提示一下 error.message
    Message.error(error.message)
  }

  // 对响应错误做点什么
  return Promise.reject(error)
})

export default instance
